package com.yxc.easyexceldemo.const_enum;

import lombok.SneakyThrows;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * @author: YXC
 * @time: 2022/11/15 11:26
 **/
public interface MEnum<T extends Enum, C> {

    @SneakyThrows
    public static MEnum staticGetByCode(Class<? extends MEnum> type, Object code) {
        Method values = type.getMethod("values");
        MEnum[] mEnums = ((MEnum[]) values.invoke(type));
        for (MEnum mEnum : mEnums) {
            if (mEnum.getCode().equals(code)) {
                return mEnum;
            }
        }
        return null;
    }

    @SneakyThrows
    static MEnum staticGetByName(Class<? extends MEnum> type, String name) {
        Method values = type.getMethod("values");
        MEnum[] mEnums = ((MEnum[]) values.invoke(type));
        for (MEnum mEnum : mEnums) {
            if (mEnum.getName().equals(name)) {
                return mEnum;
            }
        }
        return null;
    }

    public C getCode();

    public String getName();

    public default T getByCode(C code) {
        try {
            Class<T> enumClass = null;
            Type genericSuperclass = getClass().getGenericSuperclass();
            if (genericSuperclass instanceof ParameterizedType) {
                ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;
                Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
                if (actualTypeArguments != null && actualTypeArguments.length > 0) {
                    enumClass = (Class<T>) actualTypeArguments[0];
                }
            }
            if (enumClass != null) {
                Method values = enumClass.getMethod("values");
                MEnum[] mEnums = ((MEnum[]) values.invoke(enumClass));
                for (MEnum mEnum : mEnums) {
                    if (mEnum.getCode().equals(code)) {
                        return (T) mEnum;
                    }
                }
            }
        } catch (Exception e) {

        }
        return null;
    }

    public default T getByName(String name) {
        try {
            Class<T> enumClass = null;
            Type genericSuperclass = getClass().getGenericSuperclass();
            if (genericSuperclass instanceof ParameterizedType) {
                ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;
                Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
                if (actualTypeArguments != null && actualTypeArguments.length > 0) {
                    enumClass = (Class<T>) actualTypeArguments[0];
                }
            }
            if (enumClass != null) {
                Method values = enumClass.getMethod("values");
                MEnum[] mEnums = ((MEnum[]) values.invoke(enumClass));
                for (MEnum mEnum : mEnums) {
                    if (mEnum.getName().equals(name)) {
                        return (T) mEnum;
                    }
                }
            }
        } catch (Exception e) {

        }
        return null;
    }

}
